package statistics;

import datastructures.UserParameters;
import edu.rit.numeric.Statistics;

public class LOD_Contrasts extends AbstractStatisticTests implements IStatisticalTest {

	public LOD_Contrasts (UserParameters userParams) {
		super(userParams);
	}
	
	@Override
	public double TestCasesOnly(int order, int[][] observedCases) 
	{
		double z_cases = TestCasesOnly_Zscore(order, observedCases);
		double probability = Statistics.chiSquarePvalue(1, Math.pow(z_cases,2)) ; // / 2;
		return probability;
	}

	@Override
	public double TestCasesOnly_Zscore(int order, int[][] observedCases) 
	{
		observedCases[1][1] = Math.max(observedCases[1][1], 1);
		observedCases[1][0] = Math.max(observedCases[1][0], 1);
		observedCases[0][1] = Math.max(observedCases[0][1], 1);
		observedCases[0][0] = Math.max(observedCases[0][0], 1);
		
		double lod_cases = Math.log( (double) (observedCases[1][1] * observedCases[0][0] ) / ( observedCases[1][0] * observedCases[0][1] ) );
		double var_cases =  ( 	((double) 1 / observedCases[1][1]) + ((double) 1 / observedCases[1][0])
										 + ((double) 1 / observedCases[0][1]) + ((double) 1 / observedCases[0][0]) );

		double z_cases = lod_cases / Math.sqrt(var_cases) ;
		return z_cases;
	}

	@Override
	public double TestCasesVsControls(int order, int[][] observedCases, int[][] observedControls) 
	{
		double z_diff = TestCasesVsControls_Zscore(order, observedCases, observedControls);
		double probability = Statistics.chiSquarePvalue(1, Math.pow(z_diff,2)) ; // / 2;
		return probability;
	}

	@Override
	public double TestCasesVsControls_Zscore(int order, int[][] observedCases, int[][] observedControls) 
	{
		observedCases[1][1] = Math.max(observedCases[1][1], 1);
		observedCases[1][0] = Math.max(observedCases[1][0], 1);
		observedCases[0][1] = Math.max(observedCases[0][1], 1);
		observedCases[0][0] = Math.max(observedCases[0][0], 1);
		
		double lod_cases = Math.log( (double) ( observedCases[1][1] * observedCases[0][0] ) / ( observedCases[1][0] * observedCases[0][1] ) );
		double var_cases =  ( 	((double) 1 / observedCases[1][1]) + ((double) 1 / observedCases[1][0])
										 + ((double) 1 / observedCases[0][1]) + ((double) 1 / observedCases[0][0]) );

		observedControls[1][1] = Math.max(observedControls[1][1], 1);
		observedControls[1][0] = Math.max(observedControls[1][0], 1);
		observedControls[0][1] = Math.max(observedControls[0][1], 1);
		observedControls[0][0] = Math.max(observedControls[0][0], 1);
		
		double lod_controls = Math.log( (double) ( observedControls[1][1] * observedControls[0][0] ) / ( observedControls[1][0] * observedControls[0][1] ) );
		double var_controls =  ( 	((double)1 / observedControls[1][1]) + ((double) 1 / observedControls[1][0])
											+ ((double) 1 / observedControls[0][1]) + ((double) 1 / observedControls[0][0]) );
		
		double z_contrast = ( lod_cases - lod_controls ) / Math.sqrt ( var_cases + var_controls ) ;
		return z_contrast;
	}

}
